package flex.cc.vehicle_svr.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import flex.cc.base.dto.LoginAuthDto;
import flex.cc.common.vo.UrgeStatus;
import flex.cc.core.utils.RequestUtil;
import flex.cc.order.manage.dto.order.OrderMainEntity;
import flex.cc.order.manage.dto.vo.OrderMainVo;
import flex.cc.order.manage.service.OrderMainService;
import flex.cc.order.manage.service.OrderTrackService;
import flex.cc.vehicle_svr.service.UrgeService;

/**
*
* @author WANGCONG
* 2021年9月8日下午7:31:23
* @desc 催单业务实现层
*/
@Service("urgeService")
@Transactional(rollbackFor = Exception.class)
public class UrgeServiceImpl implements UrgeService{

	@Resource
    private OrderMainService orderMainService;
	@Resource
    private OrderTrackService orderTrackService;
    
	/**
	*
	* @author WANGCONG
	* 2021年9月8日下午9:42:13
	* @desc 催单请求下游（页面操作）
	*/
	@Override
	public Map<String, String> urgeToDown(List<OrderMainVo> orderList) {
		
		LoginAuthDto loginUser = RequestUtil.getLoginUser();
		String userCode = loginUser.getUserCode();
		
		Map<String,String> resultMap = new HashMap<>();
		//开启线程池并发调用下游
		ExecutorService pool = Executors.newFixedThreadPool(orderList.size());
		//创建多个有返回值的任务
		List<Future> list = new ArrayList<Future>();
		for(int i=0; i<orderList.size(); i++){
			Callable c = new MyCallable(orderList.get(i), userCode);
			//执行任务并获取Future对象
			Future f = pool.submit(c);
			list.add(f);
		}
		pool.shutdown();
		List<String> result = new ArrayList<>(); //存放催单失败的服务单号
		try {
			for (Future f : list) {
				String s = (String) f.get();
				result.add(s);
			}
			result.removeAll(Collections.singleton(null));
			String response = StringUtils.join(result.toArray(),",");
			if(StringUtils.isNotEmpty(response)){
				resultMap.put("code", "500");
				resultMap.put("msg", response);
			}else{
				resultMap.put("code", "200");
				resultMap.put("msg", "催单成功");
			}
		} catch (Exception e) {
			e.printStackTrace();
			resultMap.put("code", "500");
			resultMap.put("msg", "催单请求失败");
		}
		return resultMap;
		
	}
	
	/**
	*
	* @author WANGCONG
	* 2021年9月8日下午10:06:52
	* @desc 多线程并发请求下游催单
	*/
	class MyCallable implements Callable<String>{
		
		private OrderMainVo orderMainVo;
		private String userCode;
		
		public MyCallable(OrderMainVo orderMainVo, String userCode) {
			this.orderMainVo = orderMainVo;
			this.userCode = userCode;
		}
		@Override
		public String call() throws Exception {
			String urgeContent = orderMainVo.getUrgeContent();//催单内容
			//数据库实时数据，做二次判断，避免页面缓存导致的数据状态不一致
			Map<String, Object> params = new HashMap<>();
			params.put("orderNo", orderMainVo.getOrderNo());
			OrderMainEntity entity = orderMainService.getOneByParams(params);
			String status = entity.getStatus();
			if(status.equals(UrgeStatus.WAIT_STATUS) || status.equals(UrgeStatus.FINISH_STATUS) || status.equals(UrgeStatus.CANCEL_STATUS)){
				return null;
			}
			Map<String, Object> postJson = new HashMap<>(); //拼接post请求报文   
            postJson.put("orderNo", orderMainVo.getOrderNo());
            postJson.put("content", urgeContent);
            postJson.put("creater", userCode);  //传递当前登录人，用作轨迹操作的创建者
            /**
             * responseMap.put("responseCode", "01");
			   responseMap.put("responseMsg", "失败");
			   responseMap.put("responseCode", "00");
			   responseMap.put("responseMsg", "成功");
             */
            Map<String, Object> responseMap = orderTrackService.urgeOrder(postJson);
            String code = (String)responseMap.get("responseCode");
            if("01".equals(code)){
            	//将失败的服务单号返回去，用于前台回显展示
            	return orderMainVo.getOrderNo();
            }
			return null;
		}
		
	}


	
	
}
